﻿from collections import deque
import platform,subprocess
from threading import  Semaphore

LOCK:Semaphore = Semaphore() # 互斥访问 UID
UID:int = 0 # 全局变量，标志连接序号

def get_UID():
    """获取一个 ID"""
    LOCK.acquire()
    global UID
    id = UID
    UID += 1
    LOCK.release()
    return id

class AData():
    def __init__(self, **kwargs) -> None:
        self.channel = kwargs["channel"] if "channel" in kwargs else None
        self.protocol = kwargs["protocol"] if "protocol" in kwargs else None
        self.err = None
        pass
    def set(self, **kwargs):
        if "channel" in kwargs: self.channel = kwargs["channel"]
        if "protocol" in kwargs: self.protocol = kwargs["protocol"]
        pass
    def get(self, v):
        return getattr(self,v)

class UI_data():
    UNAME:list = list(platform.uname())
    def __init__(self) -> None:
        if(self.UNAME[0] == "Windows"):
            self.startupinfo = subprocess.STARTUPINFO() # 使 subprocess.Popen 调用时不出现一闪而过的窗口
            self.startupinfo.dwFlags = subprocess.CREATE_NEW_CONSOLE | subprocess.STARTF_USESHOWWINDOW
            self.startupinfo.wShowWindow = subprocess.SW_HIDE
        elif(self.UNAME[0] == "Linux"):
            pass
        self.root = None
        self.sml = None
        self.smf = None
        self.sms = None
        self.dqrecv:deque = None
        self.dqsend:deque = None
        self.ADATA:dict = None # 所有数据保存在此, 每个数据的结构为 AData
        pass
 
    def log(self, t, m):
        self.smf.log(t, m)
    
    def show(self, data:AData):
        """显示某一通道"""
        self.sml.show(data)
        self.smf.show(data)
        self.sms.show(data)
    
    def update(self, data:AData):
        """更新显示"""
        self.sms.update(data)
        
    def enable(self, data:AData):
        """通道在创建时都是没有启动的，同时对应的窗口也是无效的，成功创建时应使这个窗口有效才可以响应点击"""
        if(data.protocol.mf): self.smf.enable(data)
        
    def disable(self, data:AData):
        """通道在创建时都是没有启动的，同时对应的窗口也是无效的，成功创建时应使这个窗口有效才可以响应点击"""
        if(data.protocol.mf): self.smf.disable(data)
        
    def shutdown(self, data:AData, do_close_fd = False):
        """关闭某个通道, 停用所有相关资源， 禁止响应"""
        if do_close_fd:
            data.channel.stop(self.dqsend)
        if(data.protocol.type == "RAW"):
            if(hasattr(data.protocol.mf, "stop") ):
                data.protocol.mf.stop() # 窗口状态更新，变为禁用
        self.log("成功", "命令关闭："+ str(data.channel.id) + ":" + data.channel.info + " / " + data.protocol.info)
        return data
        
        
    def remove(self, data:AData):
        """关闭某个通道, 回收所有相关资源"""
        self.shutdown(data, True)
        self.sml.remove(data)
        self.smf.remove(data)
        self.sms.remove(data)
        self.log("成功", "命令删除："+ str(data.channel.id) + ":" + data.channel.info + " / " + data.protocol.info)
        self.ADATA.pop(data.channel.id)
        pass
 